/**
 * 自定义 request 网络请求工具,基于axios
 * @author LiQingSong
 */
import axios, { AxiosPromise, AxiosRequestConfig, AxiosResponse } from 'axios'
import { notification, message } from 'ant-design-vue'
import { API_ROOT_NEW as API_ROOT, CLIENTID, CLIENT_SECRET_NEW as CLIENT_SECRET } from '@/config/env'
import { removeToken } from '@/utils/localToken'
import { clearStore, getStore } from './store'
import md5 from 'md5'
import { getUrlParams } from './common'
import qs from 'qs'

export interface ResponseData {
  code: number
  data?: any
  msg?: string
  accessToken?: string
}

const customCodeMessage: { [key: number]: string } = {
  10002: '当前用户登入信息已失效，请重新登入再操作', // 未登陆
}

const serverCodeMessage: { [key: number]: string } = {
  200: '服务器成功返回请求的数据',
  400: 'Bad Request',
  401: 'Unauthorized',
  403: 'Forbidden',
  404: 'Not Found',
  500: '服务器发生错误，请检查服务器(Internal Server Error)',
  502: '网关错误(Bad Gateway)',
  503: '服务不可用，服务器暂时过载或维护(Service Unavailable)',
  504: '网关超时(Gateway Timeout)',
}

/**
 * 异常处理程序
 */
const errorHandler = (error: any, config: any) => {
  console.log(error)

  const { response } = error
  if (error.message === 'CancelToken') {
    // 取消请求 Token
    // eslint-disable-next-line no-console
  } else if (response && response.status) {
    const errorText = serverCodeMessage[response.status] || response.statusText
    const { status, request } = response
    if (error.response.status === 401) {
      clearStore()
      removeToken()
      
    } else if (error.response.status === 400) {
      message.error(error.response.data ? error.response.data.msg : errorText)
      return error.response.data
    } else {
      // isNoMessageErr传参报错不显示 特殊需求-开单-isNoMessageErr：true 选择车辆-获取vin码不提示报错
      if (config.params && config.params.isNoMessageErr) {
        return
      }
      message.error(error.response.data ? error.response.data.msg : errorText)
      // notification.error({
      //   message: `请求错误 ${status}:`,// ${request.responseURL}
      //   description: errorText,
      // });
      // if (error.response.data?.code == '10001') {
      //   // 只针对总检接口
      //   return error.response.data
      // }
      // 10001只针对总检接口
      // 10003 vin解析 vin码输入有误，请输入正确vin码/车架号可能有误，请核实车架号！
      // 4001 车架号解析失败，请选择品牌车型！
      // 4003 VIN码已存在
      if ([10001, 10003, 4001, 4003].includes(error.response.data?.code)) {
        return error.response.data
      }
    }
  } else if (!response) {
    notification.error({
      description: '您的网络发生异常，无法连接服务器',
      message: '网络异常',
    })
  }
  return error.response.data
}

/**
 * 配置request请求时的默认参数
 */
const request = axios.create({
  baseURL: API_ROOT, //process.env.VUE_APP_API_ROOT,
  // baseURL: process.env.VUE_APP_APIHOST, // url = api url + request url
  // withCredentials: true, // 当跨域请求时发送cookie
  timeout: 0, // 请求超时时间,5000(单位毫秒) / 0 不做限制
})

//正式，灰度，测试接口地址区分。

const PAY_APP_KEY: any = process.env.VUE_APP_PAY_APP_KEY
const whiteList = ['/user/login']

request.interceptors.request.use(
  (req: any) => {
    // 下面这些是非支付那些的接口
    if (!req.params) {
      req.params = {}
    }
    // if(req.baseURL=='https://mock.apifox.cn/m1/1749438-0-default'){
    //   let first = req.url.indexOf("/")+1
    //   let second = req.url.indexOf("/", first)+1;
    //   req.url = req.url.substring(second,req.url.length)

    // }

    req.params.timestamp = new Date().getTime()
    req.params.platform = 50

    if (!whiteList.find((item) => req.url?.indexOf(item) > -1)) {
      const token = getStore('userInfoNew').accessToken

      console.log(token, 'token')

      req.params.accessToken = token

      const newToken = getStore('newToken')
      req.headers['Authorization'] = `Bearer ${newToken}`
    }
    if (!req.params?.ignoreNull) {
      for (const key in req.params) {
        if (req.params[key] === null || req.params[key] === undefined || req.params[key] === '' || JSON.stringify(req.params[key]) == '{}') {
          delete req.params[key]
        }
      }
    }
    if (!req.data?.ignoreNull) {
      for (const key in req.data) {
        if (req.data[key] === null || req.data[key] === undefined || req.data[key] === '' || JSON.stringify(req.data[key]) == '{}') {
          delete req.data[key]
        }
      }
    }

    const clientId = CLIENTID
    const clientSecret = CLIENT_SECRET
    let signCode
    if (req.params && typeof req.params === 'object' && req.params['cType']) {
      delete req.params.cType
      const paramsStr = qs.stringify(req.params)
      signCode = md5(`${paramsStr}+${clientSecret}`)
    } else if (req.data && typeof req.data === 'object' && req.data['isSignatur']) {
      const a: any = {}
      delete req.data.isSignatur
      const obj: any = Object.assign(req.params, req.data)
      for (const key in obj) {
        if (obj.hasOwnProperty(key)) {
          a[key] = typeof obj[key] === 'object' ? JSON.stringify(obj[key]) : obj[key]
        }
      }
      const paramsStr = `${getUrlParams(a)}`
      req.data = ''

      signCode = md5(paramsStr)
    } else if (req.method === 'get' || req.method === 'delete') {
      const a: any = {}
      for (const key in req.params) {
        if (req.params.hasOwnProperty(key)) {
          a[key] = typeof req.params[key] === 'object' ? JSON.stringify(req.params[key]) : req.params[key]
        }
      }
      const paramsStr = `${getUrlParams(a)}`
      signCode = md5(paramsStr)
    } else {
      const data = req.data || {}
      if (data.clientSecret) {
        data.clientSecret = md5(data.clientSecret)
        const paramsStr = `${getUrlParams(req.params)}+${JSON.stringify({
          ...data,
        })}+${clientSecret}`
        signCode = md5(paramsStr)
      } else {
        const paramsStr = `${getUrlParams(req.params)}+${JSON.stringify(data)}`
        signCode = md5(paramsStr)
      }
    }

    req.headers['signCode'] = signCode
    req.headers['clientId'] = clientId
    if (req.params['export'] || req.data?.export) {
      //请求导出文件时设置
      req.responseType = 'blob'
    } else {
      req.responseType = 'json'
    }
    return req
  },
  (error) => {
    Promise.reject(error)
  }
)
/**
 * 请求后
 * 响应拦截器
 */

request.interceptors.response.use(
  (response) => {
    if (response.request.responseType == 'blob') {
      return response
      // vin码解析接口 4003 VIN码已存在
    } else if (response.data.code !== 1 && response.data.code !== 4003) {
      message.error(response.data.msg || '网络异常～')
      return response
    } else {
      return response
    }
  },
  (error) => {
    return Promise.reject(error)
  }
)

export default function (config: any): AxiosPromise<any> {
  return request(config)
    .then((response: AxiosResponse) => (response.request.responseType == 'blob' ? response : response.data))
    .catch((error) => errorHandler(error, config))
}
